#include "dt2821b.h"
#include <QPainter>
#include <QPen>
#include <QStyleOptionGraphicsItem>
#include <QPainterPath>
#include <QPolygonF>
#include <QtDebug>
#include "../../aurasim.h"

DT2821B::DT2821B(QGraphicsItem* parent):
    Entity (parent),
    mSize(120, 80)
{
    setName("DT2821B");
    for(int i = 0; i < 10; i++) {
        QSharedPointer<RoundPinEntity> pin(new RoundPinEntity(this));
        Aurasim::entityManager()->addSubEntity(pin.data());
        pin->setPinVal(0);
        pin->setPinMode(0);

        qreal x, y;
        if(i < 5) {
            x = -mSize.width() / 2 + 20 + i * 20;
            y = mSize.height() / 2;
            pin->setPinDirection(Down);
        } else{
            x = mSize.width() / 2 - 20 - (i - 5) * 20;
            y = -mSize.height() / 2;
            pin->setPinDirection(Up);
        }

        pin->setPos(QPointF(x, y));
        mpins.append(pin);
    }

    // by default pins 5 and 8 have default current nodes pointing to every pins(except pins 5 and 8).
    for(int i = 0; i < 10; i++) {
        if(i == 5 || i == 8)
            continue;
        mpins[5]->addCurrentNode(mpins[i]->id());
        mpins[8]->addCurrentNode(mpins[i]->id());
    }

    // 1
    QPolygonF a1polygon;
    a1polygon << QPointF(-mSize.width() / 2 + 15, -mSize.height() / 2 + 10)
              << QPointF(-mSize.width() / 2 + 15 + 5, -mSize.height() / 2 + 10 - 2)
              << QPointF(-mSize.width() / 2 + 15 + 25, -mSize.height() / 2 + 10 - 2)
              << QPointF(-mSize.width() / 2 + 15 + 30, -mSize.height() / 2 + 10)
              << QPointF(-mSize.width() / 2 + 15 + 25, -mSize.height() / 2 + 10 + 2)
              << QPointF(-mSize.width() / 2 + 15 + 5, -mSize.height() / 2 + 10 + 2)
              << QPointF(-mSize.width() / 2 + 15, -mSize.height() / 2 + 10);
    mpa1.addPolygon(a1polygon);

    QPolygonF b1polygon;
    b1polygon << QPointF(-15, -mSize.height() / 2 + 10)
              << QPointF(-15 + 2, -mSize.height() / 2 + 10 + 5)
              << QPointF(-15 + 2, -5)
              << QPointF(-15, 0)
              << QPointF(-15 - 2, -5)
              << QPointF(-15 - 2, -mSize.height() / 2 + 10 + 5)
              << QPointF(-15, -mSize.height() / 2 + 10);
    mpb1.addPolygon(b1polygon);

    QPolygonF c1polygon;
    c1polygon << QPointF(-15, 0)
              << QPointF(-15 + 2, 5)
              << QPointF(-15 + 2, mSize.height() / 2 - 10 - 5)
              << QPointF(-15, mSize.height() / 2 - 10)
              << QPointF(-15 - 2, mSize.height() / 2 - 10 - 5)
              << QPointF(-15 - 2, 5)
              << QPointF(-15, 0);
    mpc1.addPolygon(c1polygon);

    QPolygonF d1polygon;
    d1polygon << QPointF(-mSize.width() / 2 + 15, mSize.height() / 2 - 10)
              << QPointF(-mSize.width() / 2 + 15 + 5, mSize.height() / 2 - 10 - 2)
              << QPointF(-mSize.width() / 2 + 15 + 25, mSize.height() / 2 - 10 - 2)
              << QPointF(-mSize.width() / 2 + 15 + 30, mSize.height() / 2 - 10)
              << QPointF(-mSize.width() / 2 + 15 + 25, mSize.height() / 2 - 10 + 2)
              << QPointF(-mSize.width() / 2 + 15 + 5, mSize.height() / 2 - 10 + 2)
              << QPointF(-mSize.width() / 2 + 15, mSize.height() / 2 - 10);
    mpd1.addPolygon(d1polygon);

    QPolygonF e1polygon;
    e1polygon << QPointF(-mSize.width() / 2 + 15, 0)
              << QPointF(-mSize.width() / 2 + 15 + 2, 5)
              << QPointF(-mSize.width() / 2 + 15 + 2, mSize.height() / 2 - 10 - 5)
              << QPointF(-mSize.width() / 2 + 15, mSize.height() / 2 - 10)
              << QPointF(-mSize.width() / 2 + 15 - 2, mSize.height() / 2 - 10 - 5)
              << QPointF(-mSize.width() / 2 + 15 - 2, 5)
              << QPointF(-mSize.width() / 2 + 15, 0);
    mpe1.addPolygon(e1polygon);

    QPolygonF f1polygon;
    f1polygon << QPointF(-mSize.width() / 2 + 15, -mSize.height() / 2 + 10)
              << QPointF(-mSize.width() / 2 + 15 + 2, -mSize.height() / 2 + 10 + 5)
              << QPointF(-mSize.width() / 2 + 15 + 2, -5)
              << QPointF(-mSize.width() / 2 + 15, 0)
              << QPointF(-mSize.width() / 2 + 15 - 2, -5)
              << QPointF(-mSize.width() / 2 + 15 - 2, -mSize.height() / 2 + 10 + 5)
              << QPointF(-mSize.width() / 2 + 15, -mSize.height() / 2 + 10);
    mpf1.addPolygon(f1polygon);

    QPolygonF g1polygon;
    g1polygon << QPointF(-mSize.width() / 2 + 15, 0)
              << QPointF(-mSize.width() / 2 + 15 + 5, - 2)
              << QPointF(-mSize.width() / 2 + 15 + 25, - 2)
              << QPointF(-mSize.width() / 2 + 15 + 30, 0)
              << QPointF(-mSize.width() / 2 + 15 + 25, 2)
              << QPointF(-mSize.width() / 2 + 15 + 5, 2)
              << QPointF(-mSize.width() / 2 + 15, 0);
    mpg1.addPolygon(g1polygon);

    // 2
    QPolygonF a2polygon;
    a2polygon << QPointF(15, -mSize.height() / 2 + 10)
              << QPointF(15 + 5, -mSize.height() / 2 + 10 - 2)
              << QPointF(15 + 25, -mSize.height() / 2 + 10 - 2)
              << QPointF(15 + 30, -mSize.height() / 2 + 10)
              << QPointF(15 + 25, -mSize.height() / 2 + 10 + 2)
              << QPointF(15 + 5, -mSize.height() / 2 + 10 + 2)
              << QPointF(15, -mSize.height() / 2 + 10);
    mpa2.addPolygon(a2polygon);

    QPolygonF b2polygon;
    b2polygon << QPointF(mSize.width() / 2 - 15, -mSize.height() / 2 + 10)
              << QPointF(mSize.width() / 2 - 15 + 2, -mSize.height() / 2 + 10 + 5)
              << QPointF(mSize.width() / 2 - 15 + 2, -5)
              << QPointF(mSize.width() / 2 - 15, 0)
              << QPointF(mSize.width() / 2 - 15 - 2, -5)
              << QPointF(mSize.width() / 2 - 15 - 2, -mSize.height() / 2 + 10 + 5)
              << QPointF(mSize.width() / 2 - 15, -mSize.height() / 2 + 10);
    mpb2.addPolygon(b2polygon);

    QPolygonF c2polygon;
    c2polygon << QPointF(mSize.width() / 2 - 15, 0)
              << QPointF(mSize.width() / 2 - 15 + 2, 5)
              << QPointF(mSize.width() / 2 - 15 + 2, mSize.height() / 2 - 10 - 5)
              << QPointF(mSize.width() / 2 - 15, mSize.height() / 2 - 10)
              << QPointF(mSize.width() / 2 - 15 - 2, mSize.height() / 2 - 10 - 5)
              << QPointF(mSize.width() / 2 - 15 - 2, 5)
              << QPointF(mSize.width() / 2 - 15, 0);
    mpc2.addPolygon(c2polygon);

    QPolygonF d2polygon;
    d2polygon << QPointF(15, mSize.height() / 2 - 10)
              << QPointF(15 + 5, mSize.height() / 2 - 10 - 2)
              << QPointF(15 + 25, mSize.height() / 2 - 10 - 2)
              << QPointF(15 + 30, mSize.height() / 2 - 10)
              << QPointF(15 + 25, mSize.height() / 2 - 10 + 2)
              << QPointF(15 + 5, mSize.height() / 2 - 10 + 2)
              << QPointF(15, mSize.height() / 2 - 10);
    mpd2.addPolygon(d2polygon);

    QPolygonF e2polygon;
    e2polygon << QPointF(15, 0)
              << QPointF(15 + 2, 5)
              << QPointF(15 + 2, mSize.height() / 2 - 10 - 5)
              << QPointF(15, mSize.height() / 2 - 10)
              << QPointF(15 - 2, mSize.height() / 2 - 10 - 5)
              << QPointF(15 - 2, 5)
              << QPointF(15, 0);
    mpe2.addPolygon(e2polygon);

    QPolygonF f2polygon;
    f2polygon << QPointF(15, -mSize.height() / 2 + 10)
              << QPointF(15 + 2, -mSize.height() / 2 + 10 + 5)
              << QPointF(15 + 2, -5)
              << QPointF(15, 0)
              << QPointF(15 - 2, -5)
              << QPointF(15 - 2, -mSize.height() / 2 + 10 + 5)
              << QPointF(15, -mSize.height() / 2 + 10);
    mpf2.addPolygon(f2polygon);

    QPolygonF g2polygon;
    g2polygon << QPointF(15, 0)
              << QPointF(15 + 5, - 2)
              << QPointF(15 + 25, - 2)
              << QPointF(15 + 30, 0)
              << QPointF(15 + 25, 2)
              << QPointF(15 + 5, 2)
              << QPointF(15, 0);
    mpg2.addPolygon(g2polygon);
}

void DT2821B::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(widget)

    QColor bgColor(40, 40, 40);
    if(option->state & QStyle::State_MouseOver || option->state & QStyle::State_Selected) {
        bgColor = bgColor.lighter(120);
    }
    painter->fillRect(boundingRect(), bgColor);

    QColor ca, cb, cc, cd, ce, cf, cg, cdp;
    QColor lowColor(70, 70, 70);

    ca = mpins.at(6)->hasCrrent() ? Qt::white : lowColor;
    cb = mpins.at(7)->hasCrrent() ? Qt::white : lowColor;
    cc = mpins.at(2)->hasCrrent() ? Qt::white : lowColor;
    cd = mpins.at(1)->hasCrrent() ? Qt::white : lowColor;
    ce = mpins.at(0)->hasCrrent() ? Qt::white : lowColor;
    cf = mpins.at(9)->hasCrrent() ? Qt::white : lowColor;
    cg = mpins.at(3)->hasCrrent() ? Qt::white : lowColor;
    cdp = mpins.at(4)->hasCrrent() ? Qt::white : lowColor;

    // 1
    if(mpins.at(8)->hasCrrent() && mpins[8]->volt() > 1) {
        painter->fillPath(mpa1, ca);
        painter->fillPath(mpb1, cb);
        painter->fillPath(mpc1, cc);
        painter->fillPath(mpd1, cd);
        painter->fillPath(mpe1, ce);
        painter->fillPath(mpf1, cf);
        painter->fillPath(mpg1, cg);
        painter->fillRect(QRectF(-10, mSize.height() / 2 - 10 - 3, 6, 6), cdp);
    } else {
        painter->fillPath(mpa1, lowColor);
        painter->fillPath(mpb1, lowColor);
        painter->fillPath(mpc1, lowColor);
        painter->fillPath(mpd1, lowColor);
        painter->fillPath(mpe1, lowColor);
        painter->fillPath(mpf1, lowColor);
        painter->fillPath(mpg1, lowColor);
        painter->fillRect(QRectF(-10, mSize.height() / 2 - 10 - 3, 6, 6), lowColor);
    }

    // 2
    if(mpins.at(5)->hasCrrent() && mpins[5]->volt() > 1) {
        painter->fillPath(mpa2, ca);
        painter->fillPath(mpb2, cb);
        painter->fillPath(mpc2, cc);
        painter->fillPath(mpd2, cd);
        painter->fillPath(mpe2, ce);
        painter->fillPath(mpf2, cf);
        painter->fillPath(mpg2, cg);
        painter->fillRect(QRectF(mSize.width() / 2 - 10, mSize.height() / 2 - 10 - 3, 6, 6), cdp);
    } else {
        painter->fillPath(mpa2, lowColor);
        painter->fillPath(mpb2, lowColor);
        painter->fillPath(mpc2, lowColor);
        painter->fillPath(mpd2, lowColor);
        painter->fillPath(mpe2, lowColor);
        painter->fillPath(mpf2, lowColor);
        painter->fillPath(mpg2, lowColor);
        painter->fillRect(QRectF(mSize.width() / 2 - 10, mSize.height() / 2 - 10 - 3, 6, 6), lowColor);
    }
}

QRectF DT2821B::boundingRect() const
{
    return QRectF(-mSize.width() / 2, -mSize.height() / 2, mSize.width(), mSize.height());
}
